# @Time : 2024-07-09 18:20
# @Author : Fioman 
# @Phone : 13149920693
"""
摘要
==================================
主要用来统计本项目中所有的代码行数,用来记录平时自己开发过程中,
代码的写的行数,本项目的目标是10万行,努力吧,小家伙,争取把这个目标
完成,10万行而已,完成10万行,看看能否成为Opencv专家Master
此代码主要用来统计.py文件,其他文件不做统计
"""
import os.path
import time

from settings import BASE_DIR


def count_code_lines(filePath):
    """
    计算统计代码的行数,包括代码,注释,还有空白
    :param filePath:要统计的代码文件全路径
    :return: 返回统计结果,空白,代码行数,还有注释
    """
    blank = 0  # 空行
    code = 0  # 代码
    note = 0  # 注释
    manyNoteFlag = False  # 多行注释
    with open(filePath, encoding="utf-8") as f:
        while True:
            line = f.readline()
            if not line:
                break
            line = line.strip()
            # print("line = {},len(line) = {}".format(line, len(line)))
            if manyNoteFlag:
                if line.strip().startswith('"""') or line.strip().startswith("'''"):
                    note += 1
                    manyNoteFlag = False
                    continue
                else:
                    note += 1
                    continue
            if len(line) <= 2:
                blank += 1
                continue
            elif line.startswith("#"):
                note += 1
                continue
            elif line.startswith('"""') or line.startswith("'''"):
                note += 1
                manyNoteFlag = True
                continue
            else:
                code += 1
                continue
    return blank, code, note


def get_now_time_str():
    """
    获取当前时间的字符串形式 2024-07-15 11:20:23
    :return:
    """
    timeNow = time.time()
    now = time.strftime("%Y-%m-%d %H-%M-%S", time.localtime(timeNow))
    return now


def get_time_by_time_str(timeStr):
    """
    根据时间的字符串,获取具体的月份天数和小时以及分
    :param timeStr: 类似"2021-04-03 13-34-46"这样的时间字符串
    :return:
    """
    month = timeStr[5:7]
    day = timeStr[8:10]
    hour = timeStr[11:13]
    minute = timeStr[14:16]
    if month.startswith("0"):
        monthList = list(month)
        monthList.pop(0)
        month = ''.join(monthList)

    if day.startswith("0"):
        dayList = list(day)
        dayList.pop(0)
        day = ''.join(dayList)

    if hour.startswith("0"):
        hourList = list(hour)
        hourList.pop(0)
        hour = ''.join(hourList)

    if minute.startswith("0"):
        minuteList = list(minute)
        minuteList.pop(0)
        minute = ''.join(minuteList)

    return int(month), int(day), int(hour), int(minute)


def count_debug_time_offset(line):
    """
    获取两次代码统计耗费时间
    :param line:
    :return:
    """
    try:
        nowTime = get_now_time_str()
        month, day, hour, minute = get_time_by_time_str(nowTime)
        lastMonth, lastDay, lastHour, lastMinute = get_time_by_time_str(line[:19])
        # 计算时间间隔.
        monthDuration = month - lastMonth
        dayDuration = day - lastDay
        hourDuration = hour - lastHour
        minuteDuration = minute - lastMinute

        if minuteDuration < 0:
            minuteDuration += 60
            hourDuration -= 1
        if hourDuration < 0:
            hourDuration += 24
            dayDuration -= 1
        if dayDuration < 0:
            dayDuration += 30
            monthDuration -= 1
        timeDuration = "{} 月 {} 天 {} 小时 {} 分".format(
            monthDuration, dayDuration, hourDuration, minuteDuration)
    except Exception as e:
        print("in count_debug_time_offset() error: {}".format(str(e)))
        return 0
    return timeDuration


def get_last_count_record(lastRecordInfo):
    """
    获取上一次统计记录,统计文件的最后一行的记录信息
    :param lastRecordInfo:最后一次(一行)的记录信息
    :return:
    """
    try:
        lineSplit = lastRecordInfo.strip().split(":")
        code = int(lineSplit[1].split(",")[0])
        note = int(lineSplit[2].split(",")[0])
        blank = int(lineSplit[3].split(",")[0])
    except Exception as e:
        print("in get_last_count_record() error: {}".format(str(e)))
        return 0, 0, 0
    return code, note, blank


if __name__ == '__main__':
    print(os.path.basename(__file__))
    countCodeRecordDir = os.path.dirname(os.path.abspath(__file__))
    countCodeRecordPath = os.path.join(countCodeRecordDir, "code_count_record.txt")
    # 如果文件不存在就创建
    try:
        f1 = open(countCodeRecordPath, "r")
        f1.close()
    except IOError:
        f2 = open(countCodeRecordPath, "w")

    pyEndFiles = []

    # 1. 首先是列出来当前项目的所有的.py文件
    for root, dirs, files in os.walk(BASE_DIR):
        for file in files:
            if not file.endswith(".py") or file == "__init__.py" or file == os.path.basename(__file__):
                continue
            pyEndFiles.append(os.path.join(root, file))

    allBlank, allCode, allNote = 0, 0, 0
    for codeFilePath in pyEndFiles:
        _, fileName = os.path.split(codeFilePath)
        fileBlank, fileCode, fileNote = count_code_lines(codeFilePath)
        allBlank += fileBlank
        allCode += fileCode
        allNote += fileNote
        print("文件 {} 的代码统计结果: 代码: {},注释: {},空白: {}".format(fileName, fileCode, fileNote, fileBlank))

    print("整个项目的统计结果: 代码: {},注释: {},空白: {}".format(allCode, allNote, allBlank))
    # 将代码统计记录写入到代码统计记录中
    with open(countCodeRecordPath, "r", encoding="utf-8") as f:
        lines = f.readlines()
        if len(lines) != 0:
            # 获取上一次的结果
            lastCode, lastNote, lastBlank = get_last_count_record(lines[-1])
            allCodeAdded = allCode - lastCode
            allNoteAdded = allNote - lastNote
            allBlankAdded = allBlank - lastBlank
            timeOffset = count_debug_time_offset(lines[-1])
        else:
            allCodeAdded = allCode
            allNoteAdded = allNote
            allBlankAdded = allBlank
            timeOffset = 0

    with open(countCodeRecordPath, 'a', encoding="utf-8") as f:
        f.write("\n")
        f.write("{} 代码统计 代码: {},注释: {},空白: {}, 增加: 代码: {},注释: {},空白: {},距离上次统计: {}".format(
            get_now_time_str(), allCode, allNote, allBlank, allCodeAdded, allNoteAdded,
            allBlankAdded, timeOffset))
